﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using XRGLib;
using Console = XRGLib.Console;
using Microsoft.Xna.Framework.Input;

namespace Examples
{
    class Example4 : ExampleBase
    {

        Surface menuSurface;
        Point playerPos;
        FieldOfView<Cell> FOV;

        int range;
        FOVMethod method;
        RangeLimitShape shape;

        public Example4(Console console, int width, int height, Game game)
            : base(console, width, height, game)
        {
            menuSurface = console.CreateSurface(50, 6);

            FOV = new FieldOfView<Cell>(map);

            playerPos = new Point(width / 2, height / 2);

            range = 20;
            method = FOVMethod.MRPAS;
            shape = RangeLimitShape.Square;
        }

        public override string Description
        {
            get { return "Field of View"; }
        }

        public override void OnKeyboard(KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.W:
                    if (playerPos.Y > 0)
                        playerPos.Y--;
                    break;

                case Keys.S:
                    if (playerPos.Y < map.Height - 1)
                        playerPos.Y++;
                    break;

                case Keys.D:
                    if (playerPos.X < map.Width - 1)
                        playerPos.X++;
                    break;

                case Keys.A:
                    if (playerPos.X > 0)
                        playerPos.X--;
                    break;

                case Keys.Space:
                    MakeMap();
                    break;

                case Keys.Add:
                    range++;
                    break;

                case Keys.Subtract:
                    if (range > 0)
                        range--;
                    break;

                case Keys.NumPad1:
                case Keys.D1:
                    if (method == FOVMethod.MRPAS)
                        method = FOVMethod.RecursiveShadowcasting;
                    else
                        method = FOVMethod.MRPAS;

                    break;

                case Keys.NumPad2:
                case Keys.D2:
                    switch(shape)
                    {
                        case RangeLimitShape.Circle:
                            shape = RangeLimitShape.Square;
                            break;

                        case RangeLimitShape.Octagon:
                            shape = RangeLimitShape.Circle;
                            break;

                        case RangeLimitShape.Square:
                            shape = RangeLimitShape.Octagon;
                            break;
                    }
                    break;

            }
        }

        public override Surface ReDraw()
        {
            surface.Clear();

            FOV.ComputeFov(playerPos.X, playerPos.Y,
                range,
                true,
                method,
                shape);

            DrawMap();
            DrawMenu();

            console.BlitAlpha(menuSurface, surface, menuSurface.Rect,
                (surface.Width - menuSurface.Width) / 2,
                surface.Height - menuSurface.Height - 1,
                0.9f);

            return base.ReDraw();
        }

        void DrawMenu()
        {
            menuSurface.DefaultBackground = Color.Beige;
            menuSurface.DefaultForeground = Color.Black;

            menuSurface.DrawFrame(menuSurface.Rect, null, true);

            menuSurface.PrintString(1, 1, string.Format("[+/-] Increase/Decrease Range, current = {0}", range));
            menuSurface.PrintString(1, 2, string.Format("[1] Toggle FOV Method, current = {0}", method));
            menuSurface.PrintString(1, 3, string.Format("[2] Toggle FOV Shape, current = {0}", shape));
            menuSurface.PrintString(1, 4, "[SPACE] New Random Map");
        }



        void DrawMap()
        {
            for (int y = 0; y < map.Height; y++)
            {
                for (int x = 0; x < map.Width; x++)
                {
                    char c;
                    Color col;

                    if(map[x,y].IsTransparent)
                    {
                        c = '.';
                    }
                    else
                    {
                        c = '#';
                    }

                    if (map[x, y].IsVisible)
                    {
                        col = Color.Gold;
                    }
                    else
                    {
                        col = Color.DarkBlue;
                    }

                    surface.PrintChar(x, y, c, col);
                }
            }

            surface.PrintChar(playerPos.X, playerPos.Y, '@', Color.White, Color.DarkRed);
        }
    }
}
